<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>在线文件传输平台</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      body {
        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        min-height: 100vh;
        padding: 20px;
      }

      .container {
        max-width: 1200px;
        margin: 0 auto;
        background: white;
        border-radius: 20px;
        box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
        overflow: hidden;
      }

      .header {
        background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
        color: white;
        padding: 30px;
        text-align: center;
      }

      .header h1 {
        font-size: 2.5rem;
        margin-bottom: 10px;
        font-weight: 300;
      }

      .header p {
        font-size: 1.1rem;
        opacity: 0.9;
      }

      .main-content {
        padding: 40px;
      }

      .upload-section {
        background: #f8f9ff;
        border-radius: 15px;
        padding: 30px;
        margin-bottom: 40px;
        border: 2px dashed #4facfe;
        transition: all 0.3s ease;
      }

      .upload-section:hover {
        border-color: #00f2fe;
        background: #f0f4ff;
      }

      .upload-area {
        text-align: center;
        cursor: pointer;
      }

      .upload-icon {
        font-size: 4rem;
        color: #4facfe;
        margin-bottom: 20px;
      }

      .upload-text {
        font-size: 1.2rem;
        color: #666;
        margin-bottom: 15px;
      }

      .upload-hint {
        color: #999;
        font-size: 0.9rem;
      }

      #fileInput {
        display: none;
      }

      .btn {
        background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
        color: white;
        border: none;
        padding: 12px 30px;
        border-radius: 25px;
        cursor: pointer;
        font-size: 1rem;
        transition: all 0.3s ease;
        margin: 10px 5px;
      }

      .btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 10px 20px rgba(79, 172, 254, 0.3);
      }

      .btn:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        transform: none;
      }

      .progress-container {
        margin: 20px 0;
        display: none;
      }

      .progress-bar {
        width: 100%;
        height: 8px;
        background: #e0e0e0;
        border-radius: 4px;
        overflow: hidden;
      }

      .progress-fill {
        height: 100%;
        background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
        width: 0%;
        transition: width 0.3s ease;
      }

      .files-section {
        background: white;
        border-radius: 15px;
        padding: 30px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
      }

      .section-title {
        font-size: 1.8rem;
        color: #333;
        margin-bottom: 25px;
        display: flex;
        align-items: center;
        gap: 10px;
      }

      .file-list {
        display: grid;
        gap: 15px;
      }

      .file-item {
        background: #f8f9ff;
        border-radius: 12px;
        padding: 20px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        transition: all 0.3s ease;
        border: 1px solid #e8ecf7;
      }

      .file-item:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
        border-color: #4facfe;
      }

      .file-info {
        display: flex;
        align-items: center;
        gap: 15px;
        flex: 1;
      }

      .file-icon {
        font-size: 2rem;
        color: #4facfe;
      }

      .file-details h3 {
        color: #333;
        font-size: 1.1rem;
        margin-bottom: 5px;
      }

      .file-meta {
        color: #666;
        font-size: 0.9rem;
      }

      .file-actions {
        display: flex;
        gap: 10px;
      }

      .btn-small {
        padding: 8px 16px;
        font-size: 0.9rem;
        border-radius: 20px;
      }

      .btn-danger {
        background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
      }

      .btn-danger:hover {
        box-shadow: 0 10px 20px rgba(255, 107, 107, 0.3);
      }

      .empty-state {
        text-align: center;
        padding: 60px 20px;
        color: #999;
      }

      .empty-icon {
        font-size: 4rem;
        margin-bottom: 20px;
        opacity: 0.5;
      }

      .notification {
        position: fixed;
        top: 20px;
        right: 20px;
        padding: 15px 25px;
        border-radius: 10px;
        color: white;
        font-weight: 500;
        z-index: 1000;
        transform: translateX(400px);
        transition: transform 0.3s ease;
      }

      .notification.show {
        transform: translateX(0);
      }

      .notification.success {
        background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
      }

      .notification.error {
        background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
      }

      @media (max-width: 768px) {
        .main-content {
          padding: 20px;
        }

        .file-item {
          flex-direction: column;
          align-items: flex-start;
          gap: 15px;
        }

        .file-actions {
          width: 100%;
          justify-content: flex-end;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="header">
        <h1>📁 在线文件传输平台</h1>
        <p>快速、安全、便捷的文件分享解决方案</p>
      </div>

      <div class="main-content">
        <!-- 文件上传区域 -->
        <div class="upload-section">
          <div
            class="upload-area"
            onclick="document.getElementById('fileInput').click()"
          >
            <div class="upload-icon">☁️</div>
            <div class="upload-text">点击选择文件或拖拽文件到此处</div>
            <div class="upload-hint">支持任何格式文件，最大支持5GB</div>
          </div>
          <input type="file" id="fileInput" multiple />

          <div class="progress-container" id="progressContainer">
            <div class="progress-bar">
              <div class="progress-fill" id="progressFill"></div>
            </div>
            <div
              id="progressText"
              style="text-align: center; margin-top: 10px; color: #666"
            ></div>
          </div>

          <div style="text-align: center; margin-top: 20px">
            <button class="btn" onclick="uploadFiles()" id="uploadBtn" disabled>
              📤 上传文件
            </button>
            <button class="btn" onclick="refreshFileList()">🔄 刷新列表</button>
          </div>
        </div>

        <!-- 文件列表区域 -->
        <div class="files-section">
          <h2 class="section-title">
            📋 文件列表
            <span
              id="fileCount"
              style="font-size: 1rem; color: #666; font-weight: normal"
            ></span>
          </h2>
          <div class="file-list" id="fileList">
            <div class="empty-state">
              <div class="empty-icon">📂</div>
              <p>暂无文件，请先上传文件</p>
            </div>
          </div>
        </div>
      </div>
    </div>

    <script>
      let selectedFiles = [];

      // 文件选择处理
      document
        .getElementById("fileInput")
        .addEventListener("change", function (e) {
          selectedFiles = Array.from(e.target.files);
          updateUploadButton();
        });

      // 拖拽上传功能
      const uploadArea = document.querySelector(".upload-area");

      uploadArea.addEventListener("dragover", function (e) {
        e.preventDefault();
        uploadArea.style.background = "#e8f4fd";
      });

      uploadArea.addEventListener("dragleave", function (e) {
        e.preventDefault();
        uploadArea.style.background = "";
      });

      uploadArea.addEventListener("drop", function (e) {
        e.preventDefault();
        uploadArea.style.background = "";
        selectedFiles = Array.from(e.dataTransfer.files);
        updateUploadButton();
      });

      function updateUploadButton() {
        const uploadBtn = document.getElementById("uploadBtn");
        if (selectedFiles.length > 0) {
          uploadBtn.disabled = false;
          uploadBtn.textContent = `📤 上传 ${selectedFiles.length} 个文件`;
        } else {
          uploadBtn.disabled = true;
          uploadBtn.textContent = "📤 上传文件";
        }
      }

      // 分片上传文件
      async function uploadFiles() {
        if (selectedFiles.length === 0) {
          showNotification("请先选择文件", "error");
          return;
        }

        const progressContainer = document.getElementById("progressContainer");
        const progressFill = document.getElementById("progressFill");
        const progressText = document.getElementById("progressText");
        const uploadBtn = document.getElementById("uploadBtn");

        progressContainer.style.display = "block";
        uploadBtn.disabled = true;

        let uploadedCount = 0;
        const totalFiles = selectedFiles.length;

        for (let i = 0; i < selectedFiles.length; i++) {
          const file = selectedFiles[i];

          try {
            progressText.textContent = `正在上传: ${file.name} (${
              i + 1
            }/${totalFiles})`;

            // 所有文件都使用分片上传
            console.log(`使用分片上传: ${file.name}, 大小: ${file.size}`);
            await uploadFileInChunks(file, progressText, progressFill);

            uploadedCount++;
            const progress = (uploadedCount / totalFiles) * 100;
            progressFill.style.width = progress + "%";
            console.log(`文件 ${file.name} 上传成功`);
          } catch (error) {
            console.error("上传错误:", error);
            showNotification(
              `文件 ${file.name} 上传失败: ${error.message}`,
              "error"
            );
          }
        }

        // 上传完成
        progressText.textContent = `上传完成! 成功上传 ${uploadedCount}/${totalFiles} 个文件`;

        if (uploadedCount > 0) {
          showNotification(`成功上传 ${uploadedCount} 个文件`, "success");
          refreshFileList();
        }

        // 重置状态
        setTimeout(() => {
          progressContainer.style.display = "none";
          progressFill.style.width = "0%";
          selectedFiles = [];
          document.getElementById("fileInput").value = "";
          updateUploadButton();
        }, 2000);
      }

      // 普通文件上传
      async function uploadFileNormal(file) {
        const formData = new FormData();
        formData.append("file", file);

        const response = await fetch("/api/upload", {
          method: "POST",
          body: formData,
        });

        if (!response.ok) {
          throw new Error(
            `HTTP错误: ${response.status} ${response.statusText}`
          );
        }

        const contentType = response.headers.get("content-type");
        if (!contentType || !contentType.includes("application/json")) {
          const text = await response.text();
          console.error("非JSON响应:", text);
          throw new Error("服务器返回了非JSON格式的响应");
        }

        const result = await response.json();
        if (!result.success) {
          throw new Error(result.error || "上传失败");
        }

        return result;
      }

      // 分片上传文件
      async function uploadFileInChunks(file, progressText, progressFill) {
        const chunkSize = 1 * 1024 * 1024; // 1MB per chunk
        const totalChunks = Math.ceil(file.size / chunkSize);
        const filename = `${Date.now()}-${file.name}`;

        console.log(`开始分片上传: ${file.name}, 总分片数: ${totalChunks}`);

        // 上传所有分片（带重试机制）
        for (let i = 0; i < totalChunks; i++) {
          const start = i * chunkSize;
          const end = Math.min(start + chunkSize, file.size);
          const chunk = file.slice(start, end);

          const maxRetries = 3;
          let retryCount = 0;
          let uploaded = false;

          while (!uploaded && retryCount < maxRetries) {
            try {
              progressText.textContent = `正在上传分片: ${file.name} (${
                i + 1
              }/${totalChunks})${
                retryCount > 0 ? ` [重试 ${retryCount}]` : ""
              }`;
              const chunkProgress = ((i + 1) / totalChunks) * 100;
              progressFill.style.width = chunkProgress + "%";

              const formData = new FormData();
              formData.append("chunk", chunk);

              const response = await fetch(
                `/api/upload-chunk?filename=${encodeURIComponent(
                  filename
                )}&chunkIndex=${i}&totalChunks=${totalChunks}&fileSize=${
                  file.size
                }`,
                {
                  method: "POST",
                  body: formData,
                }
              );

              if (!response.ok) {
                throw new Error(
                  `分片 ${i} 上传失败: ${response.status} ${response.statusText}`
                );
              }

              const result = await response.json();
              if (!result.success) {
                throw new Error(`分片 ${i} 上传失败: ${result.error}`);
              }

              console.log(`分片 ${i + 1}/${totalChunks} 上传成功`);
              uploaded = true;
            } catch (error) {
              retryCount++;
              console.error(
                `分片 ${i} 上传失败 (尝试 ${retryCount}/${maxRetries}):`,
                error
              );

              if (retryCount >= maxRetries) {
                throw new Error(
                  `分片 ${i} 上传失败，已重试 ${maxRetries} 次: ${error.message}`
                );
              }

              // 等待后重试
              await new Promise((resolve) =>
                setTimeout(resolve, 1000 * retryCount)
              );
            }
          }
        }

        // 合并分片
        progressText.textContent = `正在合并文件: ${file.name}`;
        console.log("开始合并分片...");

        const mergeResponse = await fetch("/api/merge-chunks", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            filename: filename,
            totalChunks: totalChunks,
            originalName: file.name,
          }),
        });

        if (!mergeResponse.ok) {
          throw new Error(
            `合并失败: ${mergeResponse.status} ${mergeResponse.statusText}`
          );
        }

        const mergeResult = await mergeResponse.json();
        if (!mergeResult.success) {
          throw new Error(`合并失败: ${mergeResult.error}`);
        }

        console.log("文件合并成功:", mergeResult.file);
        return mergeResult;
      }

      // 获取文件列表
      async function refreshFileList() {
        try {
          const response = await fetch("/api/files");
          const result = await response.json();

          if (result.success) {
            displayFileList(result.files);
          } else {
            throw new Error(result.error || "获取文件列表失败");
          }
        } catch (error) {
          console.error("获取文件列表错误:", error);
          showNotification("获取文件列表失败", "error");
        }
      }

      // 显示文件列表
      function displayFileList(files) {
        const fileList = document.getElementById("fileList");
        const fileCount = document.getElementById("fileCount");

        fileCount.textContent = `(${files.length} 个文件)`;

        if (files.length === 0) {
          fileList.innerHTML = `
                    <div class="empty-state">
                        <div class="empty-icon">📂</div>
                        <p>暂无文件，请先上传文件</p>
                    </div>
                `;
          return;
        }

        fileList.innerHTML = files
          .map(
            (file) => `
                <div class="file-item">
                    <div class="file-info">
                        <div class="file-icon">${getFileIcon(
                          file.originalName
                        )}</div>
                        <div class="file-details">
                            <h3>${file.originalName}</h3>
                            <div class="file-meta">
                                ${formatFileSize(file.size)} • ${formatDate(
              file.uploadTime
            )}
                            </div>
                        </div>
                    </div>
                    <div class="file-actions">
                        <button class="btn btn-small" onclick="downloadFile('${
                          file.filename
                        }', '${file.originalName}')">
                            💾 下载
                        </button>
                        <button class="btn btn-small btn-danger" onclick="deleteFile('${
                          file.filename
                        }', '${file.originalName}')">
                            🗑️ 删除
                        </button>
                    </div>
                </div>
            `
          )
          .join("");
      }

      // 下载文件
      function downloadFile(filename, originalName) {
        const link = document.createElement("a");
        link.href = `/api/download/${filename}`;
        link.download = originalName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        showNotification(`开始下载: ${originalName}`, "success");
      }

      // 删除文件
      async function deleteFile(filename, originalName) {
        if (!confirm(`确定要删除文件 "${originalName}" 吗？`)) {
          return;
        }

        try {
          const response = await fetch(`/api/files/${filename}`, {
            method: "DELETE",
          });

          const result = await response.json();

          if (result.success) {
            showNotification(`文件 "${originalName}" 删除成功`, "success");
            refreshFileList();
          } else {
            throw new Error(result.error || "删除失败");
          }
        } catch (error) {
          console.error("删除文件错误:", error);
          showNotification(`删除文件失败: ${error.message}`, "error");
        }
      }

      // 工具函数
      function getFileIcon(filename) {
        const ext = filename.split(".").pop().toLowerCase();
        const iconMap = {
          pdf: "📄",
          doc: "📝",
          docx: "📝",
          txt: "📄",
          jpg: "🖼️",
          jpeg: "🖼️",
          png: "🖼️",
          gif: "🖼️",
          svg: "🖼️",
          mp4: "🎬",
          avi: "🎬",
          mov: "🎬",
          wmv: "🎬",
          mp3: "🎵",
          wav: "🎵",
          flac: "🎵",
          zip: "📦",
          rar: "📦",
          "7z": "📦",
          js: "💻",
          html: "💻",
          css: "💻",
          py: "💻",
          java: "💻",
        };
        return iconMap[ext] || "📄";
      }

      function formatFileSize(bytes) {
        if (bytes === 0) return "0 Bytes";
        const k = 1024;
        const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
      }

      function formatDate(dateString) {
        const date = new Date(dateString);
        return date.toLocaleString("zh-CN");
      }

      function showNotification(message, type = "success") {
        const notification = document.createElement("div");
        notification.className = `notification ${type}`;
        notification.textContent = message;
        document.body.appendChild(notification);

        setTimeout(() => notification.classList.add("show"), 100);
        setTimeout(() => {
          notification.classList.remove("show");
          setTimeout(() => document.body.removeChild(notification), 300);
        }, 3000);
      }

      // 页面加载时获取文件列表
      document.addEventListener("DOMContentLoaded", function () {
        refreshFileList();
      });
    </script>
  </body>
</html>
